package cn.itsource.org.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.itsource.basic.domain.BaseDomain;
import cn.itsource.basic.query.BaseQuery;
import cn.itsource.basic.query.PageList;
import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.utils.RedisService;
import cn.itsource.org.domain.Department;
import cn.itsource.org.mapper.DepartmentMapper;
import cn.itsource.org.query.DepartmentQuery;
import cn.itsource.org.service.IDepartmentService;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class DepartmentServiceImpl extends BaseServiceImpl<Department,DepartmentQuery> implements IDepartmentService {

    @Autowired
    private DepartmentMapper mapper;


    @Autowired
    private RedisService redisService;

    @Override
    public List<Department> getAll() {
        return mapper.selectAll();
    }

    @Override
    public PageList<Department> getAllByPage(DepartmentQuery query) {
        // 1. 设置分页参数
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        // 2. 执行查询操作
        List<Department> departments = mapper.getAllDept(query);
        // 3. 封装分页数据
        PageInfo<Department> pageInfo = new PageInfo<>(departments);
        // 4. 使用自己的工具类返回分页数据
        PageList<Department> pageList = new PageList<>(pageInfo.getTotal(), pageInfo.getList());
        // 5. 返回数据
        return pageList;
    }

/*    @Override
    @Transactional
    @CacheEvict(cacheNames = "treeDept",key = "'tree'")            // SpringEL表达式规定
    public void delete(Long id) {
        mapper.deleteByPrimaryKey(id);
        // 删除Redis缓存服务器里面的部门树数据
        redisService.deleteRedisByKey("reeData");
    }*/

/*    @Override
    @Transactional
    @CacheEvict(cacheNames = "treeDept",key = "'tree'")            // SpringEL表达式规定
    public void saveOrUpdate(Department department) {
        // 如果id有值就是修改，否则就是新增
        if (department.getId() == null) {
            mapper.insertSelective(department);
        }
        // 修改
        updateDept(department);

        // 删除Redis缓存服务器里面的部门树数据
        redisService.deleteRedisByKey("reeData");
    }*/


    private void updateDept(Department department) {
        // 2. 获取父级数据
        Long[] parentIds = department.getParentIds();
        // 3. 判空
        if (parentIds != null && parentIds.length > 0) {
            // 4. 创建一个字符操作对象
            StringBuffer sb = new StringBuffer();
            // 5. 遍历parentIds
            for (int i = 0; i < parentIds.length; i++) {
                sb.append("/" + parentIds[i]);            //  /3/8/9/11
            }
            // 6. 将当前数据的主键添加到dir_path的最后面
            sb.append("/" + department.getId());
            // 7. 给department进行赋值
            department.setDirPath(sb.toString());
            department.setParentId(parentIds[parentIds.length - 1]);
            // 8. 执行修改操作
            mapper.updateByPrimaryKeySelective(department);
        }
    }

    /**
     * 拿到部门树的数据
     * @return
     */
    @Override
    @Cacheable(cacheNames = "treeDept",key = "'tree'")            // SpringEL表达式规定
    public List<Department> treeDept() {
        System.out.println("我进来了。。。。。。。");
        return getDepartments();

/*        // 1. 查询缓存
        String data = redisService.getKeyObjectValue("reeData", String.class);
        // 2. 判断缓存里面是否存在部门树数据
        // 3. 如果有，则直接返回回去
        // 4. 如果没有，去数据库查询，然后将查询结果放到缓存中，再返回回去
        if (StrUtil.isEmpty(data)) {
            // 调用树形数据生成的方法
            List<Department> departments = getDepartments();
            // 将json字符串类型的部门树数据放入redis服务器中
            redisService.setStringKeyAndValue("reeData", departments);
            // 再返回数据
            return departments;
        } else {
            List<Department> list = (List<Department>) JSONObject.parse(data);
            return list;
        }*/
    }

    /**
     * 查询部门树的方法
     * contr  +  alt  + m
     * @return
     */
    private List<Department> getDepartments() {
        // 1. 拿到所有的部门数据
        List<Department> departments = mapper.selectAll();
        // 2. 创建一个空的集合
        List<Department> treeList = new ArrayList<>();
        // 3. 将所有的部门数据放入map集合中
        Map<Long, Department> map = new HashMap<>();
        for (Department dept : departments) {
            map.put(dept.getId(), dept);
        }
        // 循环所有的部门数据然后将数据放入部门中
        for (Department dept : departments) {
            if (dept.getParentId() == null) {
                treeList.add(dept);
            } else {
                // 1. 通过当前子集对象的父id找到父级对象
                Department department = map.get(dept.getParentId());
                // 2. 把当前正在循环的子集对象添加到父级的children里面
                department.getChildren().add(dept);
            }
        }
        return treeList;
    }


    @Override
    public List<Department> getParentDept() {
        return mapper.getParentDept();
    }
}
